use core::{
    future::Future,
    pin::Pin,
    task::{Context, Poll, Waker},
};

use ch32l1::ch32l103::{Peripherals, USART1};
use embedded_io::{ErrorKind, ErrorType};

use crate::runtime;

// Future原则，在实际执行异步操作前，将task的active设为false
pub struct DmaWriteFuture {
    count: usize,
    waker: Option<Waker>,
}

impl Future for DmaWriteFuture {
    type Output = ();

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
        unsafe { runtime::wakers.insert(31, cx.waker().clone()) };
        Poll::Pending
    }
}

pub struct MyUsart<'a> {
    usart: &'a USART1,
    peripherals: &'a Peripherals,
    dma_receive_addr: *mut [u8; 1024],
}
impl<'a> MyUsart<'a> {
    pub fn new(
        usart: &'a USART1,
        peripherals: &'a Peripherals,
        dma_receive_addr: *mut [u8; 1024],
    ) -> Self {
        // 配置相应GPIO
        peripherals
            .GPIOA
            .cfghr
            .modify(|_, w| w.cnf9().variant(0b10).mode9().variant(0b11));

        //PA10 上拉输入
        peripherals.GPIOA.outdr.modify(|_, w| w.odr10().set_bit());
        peripherals
            .GPIOA
            .cfghr
            .modify(|_, w| w.cnf10().variant(0b10).mode10().variant(0b00));
        // 使能USART1时钟
        peripherals
            .RCC
            .apb2pcenr
            .modify(|_, w| w.usart1en().set_bit());
        usart.ctlr1.modify(|_, w| {
            w.ue()
                .set_bit()
                .te()
                .set_bit()
                .m()
                .clear_bit()
                .pce()
                .clear_bit()
                .re()
                .set_bit()
        });
        usart.ctlr2.modify(|_, w| w.stop().variant(0b00));
        // 设置PCLK2波特率，usart1的基频率为PCLK2
        // 首先设置HB分频器 不分频
        peripherals
            .RCC
            .cfgr0
            .modify(|_, w| w.hpre().variant(0b0000));
        // 设置PB2分频器 不分频
        peripherals
            .RCC
            .cfgr0
            .modify(|_, w| w.ppre2().variant(0b000));
        // 现在可得，PB2的频率等于SYSCLK
        let pclk2 = crate::get_current_freq(peripherals);
        // 52.0833333333
        usart
            .brr
            .write(|w| w.div_mantissa().variant(52).div_fraction().variant(1));

        // DMA时钟？
        peripherals.RCC.ahbpcenr.modify(|_, w| w.dmaen().set_bit());
        // 使能DMA
        usart.ctlr3.modify(|_, w| w.dmar().set_bit());
        // DMA 外设地址
        peripherals
            .DMA
            .paddr5
            .modify(|_, w| w.pa().variant(peripherals.USART1.datar.as_ptr() as u32));
        // DMA 内存地址
        peripherals
            .DMA
            .maddr5
            .modify(|_, w| w.ma().variant(dma_receive_addr as u32));
        // DMA 传输数目
        peripherals.DMA.cntr5.modify(|_, w| w.ndt().variant(2));
        // DMA 传输完成中断使能,循环使能
        peripherals.DMA.cfgr5.modify(|_, w| {
            w.tcie()
                .set_bit()
                .circ()
                .set_bit()
                .en()
                .set_bit()
                .minc()
                .set_bit()
        });

        while usart.statr.read().txe().bit_is_clear() {}
        usart.datar.write(|w| w.dr().variant(b'A' as u16));

        MyUsart {
            usart,
            peripherals,
            dma_receive_addr,
        }
    }
    pub async fn dma_write(&self) -> DmaWriteFuture {
        return DmaWriteFuture {
            count: 3,
            waker: None,
        };
    }
}
impl<'a> ErrorType for MyUsart<'a> {
    type Error = ErrorKind;
}

impl<'a> embedded_io::Write for MyUsart<'a> {
    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
        buf.iter().for_each(|data| {
            while self.usart.statr.read().txe().bit_is_clear() {}
            self.usart.datar.write(|w| w.dr().variant(*data as u16));
        });
        return Ok(buf.len());
    }

    fn flush(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }
}

fn a() {
    panic!()
}
